import java.util.*;
/**
 * @info    Klasse, welke een compleet process van het programma simuleerd.
 * @author  (Stephan Veenstra, Michel Jansma) 
 * @version (2012.10.02)
 */

public class CanteenSimulation {
    // Canteen
    private Canteen canteen;
    
    //Supply
    private CanteenSupply supply;
    
    //Random generator
    private Random random;
    
    // aantal artikelen
    private static final int AMOUNT_ARTICLES = 4;
    
    // Artikelen
    private static final String[] articleNames = new String[]{
        "Koffie", "Broodje hamburger","Broodje kaas", "Melk" };
        
    //prijzen
    private static double[] articlePrices = new double[]{
        1.50,2.10,1.65,1.65};
        
    // minimum en maximum aantal artikelen per soort
    private static final int MIN_ARTICLES_PER_KIND = 10;
    private static final int MAX_ARTICLES_PER_KIND = 20;
    
    // minimum en maximum aantal personen per dag
    private static final int MIN_PERSONS_PER_DAY = 50;
    private static final int MAX_PERSONS_PER_DAY = 100;
    
    // minimum en maximum artikelen per persoon
    private static final int MIN_ARTICLES_PER_PERSON = 1;
    private static final int MAX_ARTICLES_PER_PERSON = 4;
    
    private static final String[] days = { "Ma", "Di", "Wo", "Do", "Vr", "Zat", "Zon" };
    
    
    /**
     * Constructor
     */
    public CanteenSimulation(){
        canteen = new Canteen();
        random = new Random();
        int[] hoeveelheden = getRandomArray(
                                AMOUNT_ARTICLES,
                                MIN_ARTICLES_PER_KIND,
                                MAX_ARTICLES_PER_KIND);
        supply = new CanteenSupply(articleNames,articlePrices, hoeveelheden); 
        canteen.setSupply(supply);
    }
    
    /**
     * Methode om een array van random getallen liggend tussen de min en max
     * van de gegeven lengte te genereren
     * @param   lengte
     * @para min
     * @param max
     * @return De array met random getallen
     */
    private int[] getRandomArray(int lengte, int min, int max){
        int[] temp = new int[lengte];
        for(int i = 0; i < lengte; i++){
            temp[i] = getRandomValue(min,max);
        }
        return temp;
    }
    
    /**
     * Methode om een random getal tussen min(incl) en max(incl) te genereren
     * @param min
     * @param max
     * @return Een random getal
     */
    private int getRandomValue(int min, int max){
        return random.nextInt(max-min+1)+min;
    }
    
    /**
     * Methode om op basis van een array van indexen voor de array
     * articleNames de bijbehorende array van articleNames te maken
     * @param indexen
     * @return De array met articleNames
     */
    private String[] getArticleNames(int[] indexen){
        String[] articles = new String[indexen.length];
        for(int i=0; i<indexen.length ; i++){
            articles[i] = articleNames[indexen[i]];
        }
        return articles;
    }
    
    /**
     * Deze methode geeft de opgegeven persoon een dienblad en en artikelen..
     */
    private void attachTray(Person persoon){
        // bedenk hoeveel artikelen worden gepakt
        int aantalArtikelen = getRandomValue(MIN_ARTICLES_PER_PERSON,MAX_ARTICLES_PER_PERSON);
        // genereer de 'artikelnummers', dit zijn de indexen
        //van de articleNames array
        int[] tepakken = getRandomArray(aantalArtikelen,0,AMOUNT_ARTICLES-1);
        // vind de articleNames op basis van de indexen hierboven
        String[] articles = getArticleNames(tepakken);
        //loop de kantine binnen, pak de gewenste artikelen, sluit aan
        canteen.personGetTrayConnectLine(persoon, articles);
    }
    
    /**
     * Deze methode simuleert een aantal dagen in de verloop van de kantine
     * @param dagen
     */
    public void simuleer(int dagen){
        
        double[] omzetten = new double[dagen];
        int[] artikelen = new int[dagen];
        
        // for lus voor de dagen
        for(int i=0;i<dagen;i++){
            ArrayList<Person> klanten = new ArrayList<Person>();
            // Genereer een x-aantal klanten
            int aantalKlanten = getRandomValue(MIN_PERSONS_PER_DAY, MAX_PERSONS_PER_DAY);
            
            // Maak het aantal persnenen aan va 3 verschillende types
            for(int j=0;j<aantalKlanten;j++){
                int x = getRandomValue(1,100);
                Person klant;
                if( x == 100){
                    klant = new Kantinemedewerker("kantine"+j,"test", true);
                } else if(x <= 10){
                    klant = new Docent("Docent"+j,"TEST", "Techniek");
                }else{
                    klant = new Student("Student"+j,"123456", "ICT");
                }
                klanten.add(klant);
            }
            // geef alle klanten een dienblad en artikelen en plaats ze in de kassa rij
            for(Person klant : klanten){
                attachTray(klant);
            }
            // verwerk de rij voor de kassa
            canteen.handleCheckoutLine();
            
            //Voeg array aan
            omzetten[i] = canteen.getCheckout().getCheckoutContent();
            artikelen[i] = canteen.getCheckout().getCheckoutArticles();
            
            //druk de dagtotalen af en hoeveel personen binnen zijn gekomen
            System.out.println("Totaal omzet: " + canteen.getCheckout().getCheckoutContent());
            System.out.println("Aantal personen: "+ klanten.size());
            System.out.println("Aantal artikelen: "+ canteen.getCheckout().getCheckoutArticles());
            //reset de kassa voor de volgende dag
            canteen.getCheckout().resetCheckout();
        }
        
        System.out.println("Gemiddelde omzet over " + dagen + " dag(en) is " + Administration.calcAverageSales(omzetten));
        System.out.println("\nEr zijn gemiddeld " + Administration.calcAverageAmount(artikelen) + " artikelen gekocht per dag.");
        //gemiddelde omzet op de dagen
        double[] omzetDagen = Administration.calcDaySales(omzetten);
        
        System.out.println("Gemiddelde omzetten gesorteerd per dag: ");
        for(int i = 0; i < omzetDagen.length; i++) {
             System.out.println(this.days[i] + ":\t€" + omzetDagen[i]);
        }
    }
    
    /**
     * Return de minimale hoeveelheid voorraad van de artikelen
     */    
    public static int getMIN(){
        return MIN_ARTICLES_PER_KIND;
    }
    
    /**
     * Return de maximale hoeveelheid voorraad van de artikelen
     */
    public static int getMAX(){
        return MAX_ARTICLES_PER_KIND;
    }
    
    /**
     * 
     */
    public void print(Person persoon){
        System.out.println(persoon.getFirstname() + " is zojuist de kantine binnengelopen.");
    }
    
}
